home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 52
/
Amiga Format AFCD52 (Issue 136, May 2000).iso
/
-serious-
/
programming
/
basic
/
mildred
/
lha
/
minimildredsourceasc.lha
/
MiniMildred.ascii
Wrap
Text File
|
1999-02-23
|
48KB
|
1,981 lines
.MiniMildred ; Mistress of chunky magic - Chunky-to-planar subsystem
;************************************************
;
;$VER:MiniMildred V1.19 (21/10/1998)-(23/02/1998)
;
;Copyright (c) 1998, Paul West.
;
;************************************************
;History
;v1.1 - First public release of full Mildred library
;v1.11 - Fixed bug in MUseShapeBank and altered ShapesTotal size to word as it was incorrectly a longword
; - Fixed bug in the errorchecking of Mc2pCPUmode that was checking d3 instead of d0
;v1.12 - Fixed bug in MUnQueue that would only do two lines of code if wrapping was active, but should have been done always
;v1.13 - MBoxF, MBoxFShape, MBoxFStencil and MBoxFCookie added
; - MBox, MBoxShape, MBoxStencil and MBoxCookie added
;v1.14 - MPlanar16ToBitmap, MPlanar16ToShape added
;v1.15 - Planar-to-chunky converter optimised further using addx and reverse bitplane order, twice as fast as roxr.b #n,dn
; - MGenericPtr added
; - A shape's handle is unconditionally added to Xpos,Ypos in MBlit,MBlock,MQBlit,MQBlock,MSBlit,MSBlock,MQSBlit,MQSBlock
;v1.16 - Fixed small bug in !PerformPoint macro, d6.l should have been d6.w.
; - Fixed small but ineffective bug in MPlotCookie, d6.l should have been d6.w
;v1.17 - Added MCludgeCookie and MCludgeStencil, also needed to add two macros
; - Fixed bug in macro used by MCludgeCookie and MCludgeStencil, as it was not setting `SHere' to 0 to indicate cludge.
;v1.18 - Added MUnQueueRange for unqueuing a range of items without flushing the queue
; - Taken out all non-c2p routines to produce mini version of library for use as c2p system only
;v1.19 - Bugfixed Mc2pWindow to store window number at start to avoid being trashed by cache flush
#MiniMildredLibNum=16
#PlaneSize=16 ; Dummy c2p SMC value
#LVOCacheClearU=-$27C
#LVOAvailMem=-$D8
#BlitzAllocmem=$c002
#BlitzFreemem=$c003
#ClearPublicMem=1|65536
#c2pWindowStructSize=4 ; LSL for 16 bytes
!libheader {#MiniMildredLibNum,Init,0,Finish,RunErrors}
;Definitions
!astatement
!args {#byte}
!libs
!subs {_Mc2pRowLacing,0,0}
!name {"MMc2pRowLacing","State.b ; Toggle row-lacing in c2p On/Off. NonZero=On"}
!astatement
!args {#byte}
!libs
!subs {_Mc2pColumnLacing,0,0}
!name {"MMc2pColumnLacing","State.b ; Toggle column-lacing in c2p On/Off"}
!astatement
!args
!libs
!subs {_Mc2pRowLaceToggle,0,0}
!name {"MMc2pRowToggle"," ; Toggle c2p row lacing between Even/Odd rows"}
!astatement
!args
!libs
!subs {_Mc2pColumnLaceToggle,0,0}
!name {"MMc2pColumnToggle"," ; Toggle c2p column lacing between Even/Odd columns"}
!astatement
!args
!libs
!subs {_Mc2pLaceToggleSingle,0,0}
!name {"MMc2pToggleSingle"," ; Toggle c2p lacing for single-buffered display"}
!astatement
!args {#byte}
!libs
!subs {_Mc2pLaceToggleDouble,_Mc2pLaceToggleDoubleCheck,0}
!name {"MMc2pToggleDouble","Buf.b ; 0 or 1. Toggle c2p lacing for double-buffered display"}
!astatement
!args {#byte}
!libs
!subs {_Mc2pLaceToggleTriple,_Mc2pLaceToggleTripleCheck,0}
!name {"MMc2pToggleTriple","Buf.b ; 0, 1 or 2. Toggle c2p lacing for triple-buffered display"}
!astatement
!args {#byte,#byte}
!libs
!subs {_Mc2pLaceToggle,_Mc2pLaceToggleCheck,0}
!name {"MMc2pToggle","Buffers.b,Buf.b ; 1, 2 or 3, and 0, 1 or 2. Toggle c2p lacing."}
!astatement
!args {#byte}
!libs
!subs {_M040c2pUsage,0,0}
!name {"MM040c2pUsage","Status.b ; On/Off - Availability of 040 c2p. Overrides Mc2pCPUmode"}
!astatement
!args {#byte}
!libs
!subs {_Mc2pCPUmode,_Mc2pCPUmodeCheck,0}
!name {"MMc2pCPUmode","CPU.b ; Set cpu c2p uses. Use Blitz's `Processor'. <4=030-, 4=040+"}
!astatement
!args {#word,#word,#word}
!libs
!subs {_Mc2pWindowBriefShort,_Mc2pWindowBriefShortCheck,0}
!args {#word,#word,#word,#byte}
!libs
!subs {_Mc2pWindowBrief,_Mc2pWindowBriefCheck,0}
!args {#word,#word,#word,#word,#word,#word}
!libs
!subs {_Mc2pWindowShort,_Mc2pWindowShortCheck,0}
!args {#word,#word,#word,#word,#byte,#word,#word}
!libs
!subs {_Mc2pWindow,_Mc2pWindowCheck,0}
!name {"MMc2pWindow","c2pWindow#.w,OpWidth.w,OpHeight.w[,SourceBWidth.w[,Processor.b],PlanarWidth.w,PlanarHeight.w]"}
!afunction {#word}
!args {#word}
!libs
!subs {_Mc2pWindowWidth,_Mc2pWindowWidthCheck,0}
!name {"MMc2pWindowWidth","(c2pWindowNumber.w) ; Returns width of c2pWindow"}
!afunction {#word}
!args {#word}
!libs
!subs {_Mc2pWindowHeight,_Mc2pWindowHeightCheck,0}
!name {"MMc2pWindowHeight","(c2pWindowNumber.w) ; Returns height of c2pWindow"}
!astatement
!args {#word,#word}
!libs
!subs {_Mc2pWindowNewHeight,_Mc2pWindowNewHeightCheck,0}
!name {"MMc2pWindowNewHeight","c2pWindow#.w,NewHeight.w ; Change height of already defined c2p object"}
!astatement
!args {#word,#long,#long}
!libs
!subs {_Mc2p,_Mc2pCheck,0}
!name {"MMc2p","c2pWindow#.w,Chunky.l,Planar.l ; Convert chunky to planar (Use Mc2pWindow first)"}
!acommand {#long}
!args {#word}
!libs
!subs {_MReservec2pWindows,_MReservec2pWindowsCheck,0}
!name {"MMReservec2pWindows","[(]NumberOfWindows.w[)] ; Reserve structure-memory for c2pWindows"}
!astatement
!args {#word,#word}
!libs
!subs {_MFreec2pWindowsRange,_MFreec2pWindowsRangeCheck,0}
!args
!libs
!subs {_MFreec2pWindows,_MFreec2pWindowsCheck,0}
!name {"MMFreec2pWindows","[Firstc2pWindow.w,Lastc2pWindow.w] ; Free/delete all/range of c2pwindows"}
!astatement
!args {#word}
!libs
!subs {_MFreec2pWindow,_MFreec2pWindowCheck,0}
!name {"MMFreec2pWindow"," Free/delete a pre-existing c2pWindow"}
!afunction {#long}
!args {#word}
!libs
!subs {_MAddrc2pWindow,_MAddrc2pWindowCheck,0}
!name {"MMAddrc2pWindow","(c2pWindowNumer.w} ; Returns address of c2pWindow structure"}
!astatement
!args {#word}
!libs
!subs {_MUsec2pWindowsShortest,_MUsec2pWindowsShortestCheck,0}
!args {#word,#word}
!libs
!subs {_MUsec2pWindowsShort,_MUsec2pWindowsShortCheck,0}
!args {#word,#word,#word}
!libs
!subs {_MUsec2pWindows,_MUsec2pWindowsCheck,0}
!name {"MMUsec2pWindows","Mainc2pWindowNum.w[,Secondc2pWindowNum.w[,Thirdc2pWindowNum.w]] ; Current to use"}
!astatement
!args {#word}
!libs
!subs {_MUsec2pWindow,_MUsec2pWindowCheck,0}
!name {"MMUsec2pWindow","c2pWindowNumber.w ; Current to use"}
!afunction {#word}
!args
!libs
!subs {_MUsedc2pWindow,_MUsedc2pWindowCheck,0}
!name {"MMUsedc2pWindow"," ; Returns currently used c2pWindow"}
!astatement
!args {#byte}
!libs
!subs {_MAutoUsec2pWindows,0,0}
!name {"MMAutoUsec2pWindows","True/False ; Automatically `use' new c2pWindows. <>0=True"}
!astatement
!args {#word,#word}
!libs
!subs {_MCopyc2pWindowStruct,_MCopyc2pWindowStructCheck,0}
!name {"MMCopyc2pWindow","Sourcec2pWindow.w,Destc2pWindow.w ; Copy definition-data only"}
!afunction {#long}
!args {#word,#word,#long,#word}
!libs
!subs {_MGenericPtr,_MGenericPtrCheck,0}
!name {"MMGenericPtr","Xpos.w,Ypos.w,BaseAddress.l,RowWidth.w ; Calculate and return address based on inputs"}
Init
!nullsub{Initialise,0,0}
Finish
!nullsub{FinishUp,0,0}
!libfin
;**-Macros-***************************************************************************
.Macros
Macro CheckAvailMem
;Having set up parameters ready to Allocmem, check it's available
;Returns success in d2
;`1=Label counter
;d0=Amount required
MOVEM.l d0/d1/a6,-(a7) ; Store
MOVE.l $4,a6 ; Execbase
AND.l #$FFFEFFFF,d1 ; Memtype without `clear'
JSR LVOAvailMem(a6)
MOVE.l d0,d2
MOVEM.l (a7)+,d0/d1/a6 ; Restore
CMP.l d0,d2
BLT CheckAvMFailed`1
MOVEM.l d0/d1/a6,-(a7) ; Store
MOVE.l $4,a6
AND.l #$FFFEFFFF,d1 ; Memtype without `clear'
OR.l #$20000,d1 ; Largest
JSR LVOAvailMem(a6)
MOVE.l d0,d2
MOVEM.l (a7)+,d0/d1/a6 ; Restore
CMP.l d0,d2
BLT CheckAvMFailed`1
MOVEQ.l #1,d2 ; Success
BRA CheckAvMSkip`1
CheckAvMFailed`1
MOVEQ.l #0,d2 ; Error
CheckAvMSkip`1
End Macro
Macro Getc2pWindowObjectPtr
;Get address of c2pWindow structure of specified c2pWindow
;d0=c2pWindow number
;Returns address in a0
AND.l #$FFFF,d0 ; Only words are valid
LSL.l #c2pWindowStructSize,d0
MOVE.l c2pWindowsMem,a0
ADD.l d0,a0
LSR.l #c2pWindowStructSize,d0 ; keep d0 intact
End Macro ; Return with a0=structure address
Macro RoundUpWidth
;Used when creating new resource to ensure width is multiple of 4 (round up)
;Trashes d7
;`1=Lable counter
;d1=Width.w
MOVE.w d1,d7 ; Temp
AND.b #$FC,d1 ; Round down width to nearest 4
AND.b #$03,d7 ; Mask off remainder bits
BEQ RoundUWskip`1
ADDQ.w #4,d1
TST.w d1 ; Has it accidentally become >signed word limit?
BGT RoundUWskip`1
SUBQ.w #4,d1 ; Can't have it rounded up, crop
RoundUWskip`1
End Macro
;**-Common-Check-Macros-**************************************************************
.CommonCheckMacros
Macro CThreec2pWindowChecks
;Three commonly used checks for c2pWindow commands
!CCheckc2pWindowsExist
!CCheckc2pWindowNum
!CCheckc2pWindowNumExists
End Macro
Macro CCheckc2pWindowNum
;Check that c2pWindow number is in valid range
TST.w d0
BLT Error0 ; Too small
CMP.w c2pWindowsTotal,d0
BGE Error0 ; Too large
End Macro
Macro CCheckc2pWindowsExist
;Check that memory has been allocated for c2pWindow objects
TST.l c2pWindowsMem ; Exist?
BEQ Error16 ; No, error
End Macro
Macro CCheckc2pWindowNumExists
;Check that a given c2pWindow object exists
!Getc2pWindowObjectPtr ; Base into a0
TST.l c2p0_Pixels-c2pWindows(a0) ; Test Pixels and RowsStore
BEQ Error17 ; Doesn't exist
End Macro
Macro CCheckWordParam
;Check that d0 word parameter is valid (not negative)
TST.w d0
BLT Error18
End Macro
Macro CCheckWordParam2
;Check that d0 word parameter is valid (not negative, and also greater than 0)
TST.w d0
BLE Error25
End Macro
;**-Routines-*************************************************************************
.Initialise
MOVE.b #0,c2pLace
MOVE.b #0,c2pLaceFrame
MOVE.b #0,c2pColumns
MOVE.b #0,c2pColumnsFrame
MOVE.b #1,c2p040useable
MOVE.b #1,c2pCPUmode
MOVE.l #0,c2pWindowsMem
MOVE.b #-1,Autoc2pWindowsUse
RTS
;*************************************************************************************
.FinishUp
RTS
;*************************************************************************************
._Mc2pRowLacing
;Switch c2p row lacing on or off (nonzero=on)
TST.b d0
BEQ c2piskip
MOVE.b #1,c2pLace
BRA c2piskip2
c2piskip
MOVE.b #0,c2pLace
c2piskip2
MOVE.b #0,c2pLaceFrame
RTS
;*************************************************************************************
._Mc2pColumnLacing
;Switch c2p column lacing on or off
TST.b d0
BEQ c2pcskip
MOVE.b #1,c2pColumns
MOVEQ.l #4*8,d7 ;-) SELF MODIFYING CODE ;-)
MOVE.l d7,c2pSMCL001-4 ; Modify a0
MOVE.l d7,c2pSMCL002-4
MOVE.l d7,c2pSMCL007-4
MOVE.l d7,c2pSMCL008-4
MOVE.l d7,c2pSMCL011-4
MOVE.l d7,c2pSMCL012-4
MOVEQ.l #4,d7
MOVE.l d7,c2pSMCL003-4 ; Modify a1/a2
MOVE.l d7,c2pSMCL004-4
MOVE.l d7,c2pSMCL005-4
MOVE.l d7,c2pSMCL006-4
MOVE.l d7,c2pSMCL009-4
MOVE.l d7,c2pSMCL010-4
MOVE.l d7,c2pSMCL013-4
MOVE.l d7,c2pSMCL014-4
BRA c2pcskip2
c2pcskip
MOVE.b #0,c2pColumns
MOVEQ.l #0,d7 ;-) SELF MODIFYING CODE ;-)
MOVE.l d7,c2pSMCL001-4 ; Modify a0/a1/a2
MOVE.l d7,c2pSMCL002-4
MOVE.l d7,c2pSMCL003-4
MOVE.l d7,c2pSMCL004-4
MOVE.l d7,c2pSMCL005-4
MOVE.l d7,c2pSMCL006-4
MOVE.l d7,c2pSMCL007-4
MOVE.l d7,c2pSMCL008-4
MOVE.l d7,c2pSMCL009-4
MOVE.l d7,c2pSMCL010-4
MOVE.l d7,c2pSMCL011-4
MOVE.l d7,c2pSMCL012-4
MOVE.l d7,c2pSMCL013-4
MOVE.l d7,c2pSMCL014-4
c2pcskip2
MOVE.b #0,c2pColumnsFrame
;Flush the cache!
MOVEM.l a3-a6,-(a7) ; Just in case
MOVE.l $4,a6
JSR LVOCacheClearU(a6)
MOVEM.l (a7)+,a3-a6 ; Restore
RTS
;*************************************************************************************
._Mc2pRowToggle
_Mc2pRowLaceToggle
;Set c2p interlacing even/odd frame
MOVEQ.l #1,d0
SUB.b c2pLaceFrame,d0
MOVE.b d0,c2pLaceFrame
RTS
;*************************************************************************************
._Mc2pColumnToggle
_Mc2pColumnLaceToggle
;Set c2p column lacing even/odd frame
MOVEQ.l #1,d0
SUB.b c2pColumnsFrame,d0
MOVE.b d0,c2pColumnsFrame
RTS
;*************************************************************************************
._Mc2pToggleSingle
_Mc2pLaceToggleSingle
MOVEQ.l #1,d0 ; Single buffered
BRA _Mc2pLaceToggle
._Mc2pToggleDouble
_Mc2pLaceToggleDouble
MOVE.l d0,d1
MOVEQ.l #2,d0 ; Double buffered
BRA _Mc2pLaceToggle
._Mc2ToggleTriple
_Mc2pLaceToggleTriple
MOVE.l d0,d1
MOVEQ.l #3,d0 ; Triple buffered
._Mc2pToggle
_Mc2pLaceToggle
;Handle c2p lacing for single, double, and triple buffered displays
SUBQ.l #1,d0 ; Buffers-1
BEQ c2pLaceSingle ; Single buffered
TST.b d1 ; Buf=0?
BNE c2pBufNot0
c2pLaceSingle
TST.b c2pLace ; Row lacing?
BEQ c2pLaceNotRow ; No, skip
BSR _Mc2pRowLaceToggle
TST.b c2pLaceFrame
BEQ c2pLaceDone
TST.b c2pColumns ; Row lacing and column lacing?
BEQ c2pLaceNotColumn ; No, skip
BSR _Mc2pColumnLaceToggle
c2pLaceNotColumn
RTS ; Done
c2pLaceNotRow
TST.b c2pColumns ; Column lacing only?
BEQ c2pLaceNotColumn2 ; No, skip
BSR _Mc2pColumnLaceToggle
c2pLaceNotColumn2
RTS
c2pBufNot0
c2pLaceDone
RTS
;*************************************************************************************
._M040c2pUsage
;Switch 040+ chunky to planar routines on or off. NonZero=On
;Note they won't be used anyway if there is no 040+ available
MOVE.b d0,c2p040useable ; Store status
RTS
;*************************************************************************************
._Mc2pCPUmode
;Set the cpu that the c2p is going to use, as there are 030- and 040+ routines
;Note that this setting is overridden by M040c2p's setting
CMP.b #4,d0 ; Check for 040
BNE c2pCPUmode030
MOVE.b #1,c2pCPUmode
RTS
c2pCPUmode030
MOVE.b #0,c2pCPUmode
RTS
;*************************************************************************************
_Mc2pWindowBriefShort
MOVE.l d1,d3
MOVE.l d1,d5
MOVE.l d2,d6
MOVE.b c2pCPUmode,d4
LSL.b #2,d4 ; Reverse engineeer cpu number
BRA _Mc2pWindow
_Mc2pWindowBrief
MOVE.l d3,d4
MOVE.l d1,d3
MOVE.l d1,d5
MOVE.l d2,d6
BRA _Mc2pWindow
_Mc2pWindowShort
MOVE.l d5,d6
MOVE.l d4,d5
MOVE.b c2pCPUmode,d4
LSL.b #2,d4 ; Reverse engineer cpu number
._Mc2pWindow
;Initialises chunky-to-planar, also self-modifies code to alter #planesize
;Note that Planar YOffset has been removed.
;d0.w=c2pWindow number
;d1.w=Chunky operation width (window width)
;d2.w=Chunky operation height (window height)
;d3.w=Source width (length of a line in the whole chunky buffer, not a window)
;d4.b=Processor (blitz instruction, will be 0/1/2/3/4)
;d5.w=Planar width (full width of bitmap)
;d6.w=Planar height (full height of bitmap)
CMP.b #4,d4 ; 040+?
BNE c2pWlowCPU2
MOVE.b #1,c2pCPUmode
BRA c2pWskip2
c2pWlowCPU2
MOVE.b #0,c2pCPUmode
c2pWskip2
AND.l #$FFFF,d0
!Getc2pWindowObjectPtr ; Get base into a0
AND.l #$FFFF,d1
AND.l #$FFFF,d2
TST.b Autoc2pWindowsUse ; Use it?
BEQ c2pWDontUse ; No
MOVE.w d0,Currentc2pWindow1 ; Yes, store c2pWindow number in current
c2pWDontUse
AND.l #$FFFF,d3
AND.l #$FFFF,d5
AND.l #$FFFF,d6
MOVE.b c2pLace,c2p0Lace-c2pWindows(a0) ; Copy row-lacing status
MOVE.w d3,c2p0LaceOffsetA-c2pWindows(a0) ; source byte offset for odd lace frames
MOVE.l d5,d7 ;temp
LSR.l #3,d7 ;bytes per line planar
MOVE.w d7,c2p0LaceOffsetB-c2pWindows(a0) ; destination byte offset for odd lace frames
MOVE.l d3,d7 ;temp
SUB.l d1,d3
TST.b c2pLace ; Check for interlace
BEQ c2pNoLace ; No
ADD.l d7,d3 ; Yes, skip 1 row in source
c2pNoLace
MOVE.w d3,c2p0_Cmod-c2pWindows(a0) ; Source chunky modulo in bytes and pixels (same)
MOVE.w d1,c2p0_Pixels-c2pWindows(a0) ; Pixels per row chunky
TST.b c2pLace ; Check for interlace
BEQ c2pNoLace2 ; No
LSR.l #1,d2 ; lines/2 ; Yes, skip every other row in number of lines
c2pNoLace2
SUBQ.l #1,d2 ; loopcounter
MOVE.w d2,c2p0_RowsStore-c2pWindows(a0) ; Chunky rows (loopcounter)
MOVE.l d5,d7 ; store
SUB.l d1,d5
TST.b c2pLace ; Check for interlace
BEQ c2pNoLace3 ; No
ADD.l d7,d5 ; skip 1 line ; Yes, skip 1 row in dest
c2pNoLace3
LSR.l #3,d5
MOVE.w d5,c2p0_Pmod-c2pWindows(a0) ; Horizontal Planar modulo in bytes
;SMC, #PlaneSize
MULU d6,d7
LSR.l #3,d7 ; PlaneSize
MOVE.l d7,c2pSMC001-4 ;-) SELF MODIFYING CODE! ;-)
MOVE.l d7,c2pSMC011-4
MOVE.l d7,c2pSMC012-4
MOVE.l d7,c2pSMC013-4
MOVE.l d7,c2pSMC014-4
MOVE.l d7,c2pSMC019-4
MOVE.l d7,c2pSMC020-4
MOVE.l d7,c2pSMC021-4
MOVE.l d7,c2pSMC026-4
MOVE.l d7,c2pSMC027-4
MOVE.l d7,c2pSMC031-4
MOVE.l d7,c2pSMC032-4
MOVE.l d7,c2pSMC037-4
MOVE.l d7,c2pSMC038-4
;SMC, #-PlaneSize
MOVEQ.l #0,d6
SUB.l d7,d6 ; d6=-PlaneSize
MOVE.l d6,c2pSMC003-4
MOVE.l d6,c2pSMC004-4
MOVE.l d6,c2pSMC005-4
MOVE.l d6,c2pSMC006-4
MOVE.l d6,c2pSMC015-4
MOVE.l d6,c2pSMC016-4
MOVE.l d6,c2pSMC017-4
MOVE.l d6,c2pSMC018-4
;SMC, #-PlaneSize-4
SUBQ.l #4,d6
MOVE.l d6,c2pSMC022-4
MOVE.l d6,c2pSMC023-4
MOVE.l d6,c2pSMC028-4
MOVE.l d6,c2pSMC029-4
MOVE.l d6,c2pSMC033-4
MOVE.l d6,c2pSMC034-4
MOVE.l d6,c2pSMC039-4
MOVE.l d6,c2pSMC040-4
;SMC, #PlaneSize*2
ADD.l d7,d7
MOVE.l d7,c2pSMC007-4
MOVE.l d7,c2pSMC008-4
MOVE.l d7,c2pSMC009-4
MOVE.l d7,c2pSMC010-4
MOVE.l d7,c2pSMC024-4
MOVE.l d7,c2pSMC025-4
MOVE.l d7,c2pSMC035-4
MOVE.l d7,c2pSMC036-4
;SMC, #PlaneSize*4
ADD.l d7,d7
MOVE.l d7,c2pSMC002-4
MOVE.l d7,c2pSMC030-4
;Flush the cache!
MOVEM.l a3-a6,-(a7) ; Just in case
MOVE.l $4,a6
JSR LVOCacheClearU(a6)
MOVEM.l (a7)+,a3-a6 ; Restore
RTS
;*************************************************************************************
._Mc2pWindowWidth
;Return the width of an existing c2pWindow object
!Getc2pWindowObjectPtr ; Base in a0
MOVE.w c2p0_Pixels-c2pWindows(a0),d0
RTS
;*************************************************************************************
._Mc2pWindowHeight
;Return the height of an existing c2pWindow object
!Getc2pWindowObjectPtr ; Base in a0
MOVE.w c2p0_RowsStore-c2pWindows(a0),d0
RTS
;*************************************************************************************
._Mc2pWindowNewHeight
;Having already initialised a c2pWindow object, change its height
MOVE.l c2pWindowsMem,a0 ; Base
EXT.l d0
LSL.l #4,d0 ; Find offset
ADD.l d0,a0 ; Point
TST.b c2p0Lace-c2pWindows(a0) ; object has data setup for row lacing?
BEQ c2pWindowNewHeightSkip
LSR.w #1,d1 ; Proposed height/2
c2pWindowNewHeightSkip
SUBQ.w #1,d1 ; Loopcounter
MOVE.w d1,c2p0_RowsStore-c2pWindows(a0) ; Store new row counter
RTS
;*************************************************************************************
._Mc2p
;AGA ChunkyToPlanar conversion.
;Different routines for 000-030 and 040-060.
;Handle c2pWindows
!Getc2pWindowObjectPtr ; Base into a0
MOVE.l a0,a2
MOVE.w c2p0_Pixels-c2pWindows(a2),c2p_Pixels
MOVE.w c2p0_RowsStore-c2pWindows(a2),c2p_RowsStore
MOVE.w c2p0_Pmod-c2pWindows(a2),c2p_Pmod
MOVE.w c2p0_Cmod-c2pWindows(a2),c2p_Cmod
MOVE.l d1,a0 ; Chunky
MOVE.l d2,a1 ; Planar
;Handle row lacing
TST.b c2pLace ; Row Interlacing?
BEQ c2pLaceSkip ; No
TST.b c2pLaceFrame ; Odd interlace row?
BEQ c2pLaceSkip
ADD.w c2p0LaceOffsetA-c2pWindows(a2),a0 ; Skip 1 chunky row
ADD.w c2p0LaceOffsetB-c2pWindows(a2),a1 ; Skip 1 planar row
c2pLaceSkip
;Handle column lacing
TST.b c2pColumns ; Columns?
BEQ c2pColumnsSkip ; No
TST.b c2pColumnsFrame ; Odd column number?
BEQ c2pColumnsSkip
ADD.w #32,a0 ; Skip 1 chunky column (32 pixels)
ADD.w #4,a1 ; Skip 1 planar column (32 pixels)
c2pColumnsSkip
MOVE.w c2p_RowsStore,c2p_Rows ; Also halfway through c2p030
MOVEM.l a3-a6,-(a7)
TST.b c2pCPUmode ; 030 routine?
BEQ c2p030
TST.b c2p040useable ; Allowed to use 040 routine?
BEQ c2p030
;Routine for 68040 and 68060.
;Used to be c2p040only.
c2p040
MOVE.w c2p_Pixels,a3
ADD.l a0,a3
ADD.l #PlaneSize,a1
c2pSMC001
MOVE.l a1,a2
ADD.l #PlaneSize*4,a2
c2pSMC002
c2p040loop
MOVE.l (a0)+,d0
MOVE.l (a0)+,d1
MOVE.l (a0)+,d2
MOVE.l (a0)+,d3
MOVE.l (a0)+,d4
MOVE.l (a0)+,d5
MOVE.l d4,d7 ; Swap 16x4, part 1
MOVE.w d0,d4
SWAP d4
MOVE.w d4,d0
MOVE.w d7,d4
MOVE.l d5,d7
MOVE.w d1,d5
SWAP d5
MOVE.w d5,d1
MOVE.w d7,d5
MOVE.l d4,d7 ; Swap 2x4, part 1
LSR.l #2,d7
EOR.l d0,d7
AND.l #$33333333,d7
EOR.l d7,d0
LSL.l #2,d7
EOR.l d7,d4
MOVE.l d5,d7
LSR.l #2,d7
EOR.l d1,d7
AND.l #$33333333,d7
EOR.l d7,d1
LSL.l #2,d7
EOR.l d7,d5
MOVE.l (a0)+,a5
MOVE.l (a0)+,a6
EXG d4,a5
EXG d5,a6
MOVE.l d4,d7 ; Swap 16x4, part 2
MOVE.w d2,d4
SWAP d4
MOVE.w d4,d2
MOVE.w d7,d4
MOVE.l d5,d7
MOVE.w d3,d5
SWAP d5
MOVE.w d5,d3
MOVE.w d7,d5
ADD.l #0,a0 ; #4*8 Custom verticle interlacing
c2pSMCL001
MOVE.l d4,d7 ; Swap 2x4, part 2
LSR.l #2,d7
EOR.l d2,d7
AND.l #$33333333,d7
EOR.l d7,d2
LSL.l #2,d7
EOR.l d7,d4
MOVE.l d5,d7
LSR.l #2,d7
EOR.l d3,d7
AND.l #$33333333,d7
EOR.l d7,d3
LSL.l #2,d7
EOR.l d7,d5
MOVE.l d1,d7 ; Swap 4x1
LSR.l #4,d7
EOR.l d0,d7
AND.l #$0f0f0f0f,d7
EOR.l d7,d0
LSL.l #4,d7
EOR.l d7,d1
MOVE.l d3,d7
LSR.l #4,d7
EOR.l d2,d7
AND.l #$0f0f0f0f,d7
EOR.l d7,d2
LSL.l #4,d7
EOR.l d7,d3
BRA c2pStart040a
c2pX040a
MOVE.l (a0)+,d0
MOVE.l (a0)+,d1
MOVE.l (a0)+,d2
ADD.l #-PlaneSize,a1
c2pSMC003
MOVE.l (a0)+,d3
MOVE.l (a0)+,d4
MOVE.l (a0)+,d5
; MOVE.l a6,-PlaneSize(a1)
MOVE.l a6,(a1)
MOVE.l d4,d7 ; Swap 16x4, part 1
MOVE.w d0,d4
SWAP d4
MOVE.w d4,d0
MOVE.w d7,d4
MOVE.l d5,d7
MOVE.w d1,d5
SWAP d5
MOVE.w d5,d1
MOVE.w d7,d5
SUB.l #-PlaneSize,a1
c2pSMC004
MOVE.l d4,d7 ; Swap 2x4, part 1
LSR.l #2,d7
EOR.l d0,d7
AND.l #$33333333,d7
EOR.l d7,d0
LSL.l #2,d7
EOR.l d7,d4
MOVE.l d5,d7
LSR.l #2,d7
EOR.l d1,d7
AND.l #$33333333,d7
EOR.l d7,d1
LSL.l #2,d7
EOR.l d7,d5
ADD.l #-PlaneSize,a2
c2pSMC005
MOVE.l (a0)+,d7
MOVE.l (a0)+,a6
; MOVE.l a5,-PlaneSize(a2)
MOVE.l a5,(a2)
MOVE.l d7,a5
EXG d4,a5
EXG d5,a6
SUB.l #-PlaneSize,a2
c2pSMC006
ADD.l #0,a0 ; #4*8Custom verticle interlacing
c2pSMCL002
MOVE.l d4,d7 ; Swap 16x4, part 2
MOVE.w d2,d4
SWAP d4
MOVE.w d4,d2
MOVE.w d7,d4
MOVE.l d5,d7
MOVE.w d3,d5
SWAP d5
MOVE.w d5,d3
MOVE.w d7,d5
MOVE.l d4,d7 ; Swap 2x4, part 2
MOVE.l d6,(a2)+
LSR.l #2,d7
EOR.l d2,d7
AND.l #$33333333,d7
EOR.l d7,d2
LSL.l #2,d7
EOR.l d7,d4
MOVE.l d5,d7
LSR.l #2,d7
EOR.l d3,d7
AND.l #$33333333,d7
EOR.l d7,d3
LSL.l #2,d7
EOR.l d7,d5
ADD.l #0,a2 ; #4 Custom verticle interlacing
c2pSMCL003
MOVE.l d1,d7 ; Swap 4x1
LSR.l #4,d7
EOR.l d0,d7
MOVE.l a4,(a1)+
AND.l #$0f0f0f0f,d7
EOR.l d7,d0
LSL.l #4,d7
EOR.l d7,d1
MOVE.l d3,d7
LSR.l #4,d7
EOR.l d2,d7
AND.l #$0f0f0f0f,d7
EOR.l d7,d2
LSL.l #4,d7
EOR.l d7,d3
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL004
c2pStart040a
ADD.l #PlaneSize*2,a2
c2pSMC007
MOVE.l d2,d7 ; Swap 8x2, part 1
LSR.l #8,d7
EOR.l d0,d7
AND.l #$00ff00ff,d7
EOR.l d7,d0
LSL.l #8,d7
EOR.l d7,d2
MOVE.l d2,d7
LSR.l #1,d7 ; Swap 1x2, part 1
EOR.l d0,d7
AND.l #$55555555,d7
EOR.l d7,d0
; MOVE.l d0,PlaneSize*2(a2)
MOVE.l d0,(a2)
ADD.l d7,d7
EOR.l d7,d2
MOVE.l d3,d7 ; Swap 8x2, part 2
LSR.l #8,d7
EOR.l d1,d7
AND.l #$00ff00ff,d7
EOR.l d7,d1
LSL.l #8,d7
EOR.l d7,d3
SUB.l #PlaneSize*2,a2
c2pSMC008
MOVE.l d3,d7
LSR.l #1,d7 ; Swap 1x2, part 2
EOR.l d1,d7
ADD.l #PlaneSize*2,a1
c2pSMC009
AND.l #$55555555,d7
EOR.l d7,d1
; MOVE.l d1,PlaneSize*2(a1)
MOVE.l d1,(a1)
ADD.l d7,d7
EOR.l d7,d3
MOVE.l d5,d7
LSR.l #4,d7
EOR.l d4,d7
AND.l #$0f0f0f0f,d7
EOR.l d7,d4
LSL.l #4,d7
EOR.l d7,d5
SUB.l #PlaneSize*2,a1
c2pSMC010
EXG d4,a5
EXG d5,a6
ADD.l #PlaneSize,a2
c2pSMC011
MOVE.l d5,d7
LSR.l #4,d7
EOR.l d4,d7
AND.l #$0f0f0f0f,d7
EOR.l d7,d4
LSL.l #4,d7
EOR.l d7,d5
MOVE.l a5,d0
MOVE.l a6,d1
; MOVE.l d2,PlaneSize(a2)
MOVE.l d2,(a2)
MOVE.l d0,d7 ; Swap 8x2, part 3
LSR.l #8,d7
EOR.l d4,d7
AND.l #$00ff00ff,d7
EOR.l d7,d4
LSL.l #8,d7
EOR.l d7,d0
SUB.l #PlaneSize,a2
c2pSMC012
MOVE.l d0,d7
LSR.l #1,d7 ; Swap 1x2, part 3
EOR.l d4,d7
AND.l #$55555555,d7
EOR.l d7,d4
ADD.l d7,d7
ADD.l #PlaneSize,a1
c2pSMC013
EOR.l d7,d0
MOVE.l d1,d7 ; Swap 8x2, part 4
LSR.l #8,d7
; MOVE.l d3,PlaneSize(a1)
MOVE.l d3,(a1)
EOR.l d5,d7
AND.l #$00ff00ff,d7
EOR.l d7,d5
LSL.l #8,d7
EOR.l d7,d1
MOVE.l d1,d7
LSR.l #1,d7 ; Swap 1x2, part 4
EOR.l d5,d7
AND.l #$55555555,d7
EOR.l d7,d5
ADD.l d7,d7
EOR.l d7,d1
SUB.l #PlaneSize,a1
c2pSMC014
MOVE.l d0,a5
MOVE.l d1,a6
MOVE.l d4,d6
MOVE.l d5,a4
CMP.l a0,a3
BGT c2pX040a
; MOVE.l a6,-PlaneSize(a1)
ADD.l #-PlaneSize,a1
c2pSMC015
MOVE.l a6,(a1)
; MOVE.l a5,-PlaneSize(a2)
ADD.l #-PlaneSize,a2
c2pSMC017
MOVE.l a5,(a2)
SUB.l #-PlaneSize,a1
c2pSMC016
MOVE.l a4,(a1)+
SUB.l #-PlaneSize,a2
c2pSMC018
MOVE.l d6,(a2)+
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL005
ADD.l #0,a2 ; #4 Custom verticle interlacing
c2pSMCL006
;YLoop
SUB.w #1,c2p_Rows
BLT c2p040skip
c2p040nextrow
ADD.w c2p_Pixels,a3 ; end of next chunky line
ADD.w c2p_Pmod,a1 ; planar dest modulo
ADD.w c2p_Pmod,a2 ; planar dest modulo
ADD.w c2p_Cmod,a0 ; chunky source modulo
ADD.w c2p_Cmod,a3 ; end of next line plus source modulo, because a0 and a3 are compared
BRA c2p040loop
c2p040skip
MOVEM.l (a7)+,a3-a6
RTS ; Finish
;Routine for 68000, 68010, 68020 and 68030.
;Used to be c2p68030only.
c2p030
MOVE.l #$33333333,d5
MOVE.l #$55555555,d6
MOVE.l #$00ff00ff,a6
ADD.l #PlaneSize,a1
c2pSMC019
MOVE.w c2p_Pixels,a2
ADD.l a0,a2
CMP.l a0,a2
BEQ c2pNone030a
MOVEM.l a0-a1,-(a7)
c2p030loop
MOVE.l (a0)+,d0
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l #$0f0f0f0f,d4 ; Merge 4x1, part 1
AND.l d4,d0
AND.l d4,d2
LSL.l #4,d0
OR.l d2,d0
AND.l d4,d1
AND.l d4,d3
LSL.l #4,d1
OR.l d3,d1
MOVE.l d1,a3
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l (a0)+,d7
AND.l d4,d2 ; Merge 4x1, part 2
AND.l d4,d1
LSL.l #4,d2
OR.l d1,d2
AND.l d4,d3
AND.l d4,d7
LSL.l #4,d3
OR.l d7,d3
MOVE.l a3,d1
ADD.l #0,a0 ; #4*8 Custom verticle interlacing
c2pSMCL007
MOVE.w d2,d7 ; Swap 16x2
MOVE.w d0,d2
SWAP d2
MOVE.w d2,d0
MOVE.w d7,d2
MOVE.w d3,d7
MOVE.w d1,d3
SWAP d3
MOVE.w d3,d1
MOVE.w d7,d3
BRA c2pStart030a
c2pX030a
ADD.l #PlaneSize,a1
c2pSMC020
MOVE.l (a0)+,d0
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
; MOVE.l d7,PlaneSize(a1)
MOVE.l d7,(a1)
MOVE.l #$0f0f0f0f,d4 ; Merge 4x1, part 1
AND.l d4,d0
AND.l d4,d2
LSL.l #4,d0
OR.l d2,d0
SUB.l #PlaneSize,a1
c2pSMC021
AND.l d4,d1
AND.l d4,d3
LSL.l #4,d1
OR.l d3,d1
MOVE.l d1,a3
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l (a0)+,d7
MOVE.l a4,(a1)+
AND.l d4,d2 ; Merge 4x1, part 2
AND.l d4,d1
LSL.l #4,d2
OR.l d1,d2
AND.l d4,d3
AND.l d4,d7
LSL.l #4,d3
OR.l d7,d3
MOVE.l a3,d1
ADD.l #0,a0 ; #4*8 Custom verticle interlacing
c2pSMCL008
MOVE.w d2,d7 ; Swap 16x2
MOVE.w d0,d2
SWAP d2
MOVE.w d2,d0
MOVE.w d7,d2
ADD.l #-PlaneSize-4,a1
c2pSMC022
MOVE.w d3,d7
MOVE.w d1,d3
SWAP d3
MOVE.w d3,d1
MOVE.w d7,d3
; MOVE.l a5,-PlaneSize-4(a1)
MOVE.l a5,(a1)
SUB.l #-PlaneSize-4,a1
c2pSMC023
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL009
c2pStart030a
MOVE.l a6,d4
MOVE.l d2,d7 ; Swap 2x2
LSR.l #2,d7
EOR.l d0,d7
AND.l d5,d7
EOR.l d7,d0
LSL.l #2,d7
EOR.l d7,d2
MOVE.l d3,d7
LSR.l #2,d7
EOR.l d1,d7
AND.l d5,d7
EOR.l d7,d1
LSL.l #2,d7
EOR.l d7,d3
ADD.l #PlaneSize*2,a1
c2pSMC024
MOVE.l d1,d7
LSR.l #8,d7
EOR.l d0,d7
AND.l d4,d7
EOR.l d7,d0
LSL.l #8,d7
EOR.l d7,d1
MOVE.l d1,d7
LSR.l #1,d7
EOR.l d0,d7
AND.l d6,d7
EOR.l d7,d0
; MOVE.l d0,PlaneSize*2(a1)
MOVE.l d0,(a1)
ADD.l d7,d7
EOR.l d1,d7
MOVE.l d3,d1
LSR.l #8,d1
EOR.l d2,d1
AND.l d4,d1
EOR.l d1,d2
LSL.l #8,d1
EOR.l d1,d3
SUB.l #PlaneSize*2,a1
c2pSMC025
MOVE.l d3,d1
LSR.l #1,d1
EOR.l d2,d1
AND.l d6,d1
EOR.l d1,d2
ADD.l d1,d1
EOR.l d1,d3
MOVE.l d2,a4
MOVE.l d3,a5
CMPA.l a0,a2
BGT c2pX030a
; MOVE.l d7,PlaneSize(a1)
ADD.l #PlaneSize,a1
c2pSMC026
MOVE.l d7,(a1)
SUB.l #PlaneSize,a1
c2pSMC027
MOVE.l a4,(a1)+
; MOVE.l a5,-PlaneSize-4(a1)
ADD.l #-PlaneSize-4,a1
c2pSMC028
MOVE.l a5,(a1)
SUB.l #-PlaneSize-4,a1
c2pSMC029
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL010
;YLoop
SUB.w #1,c2p_Rows
BLT c2p030skip
c2p030nextrow
ADD.w c2p_Pixels,a2 ; End of next chunky line
ADD.w c2p_Pmod,a1 ; Planar dest modulo
ADD.w c2p_Cmod,a0 ; Chunky source modulo
ADD.w c2p_Cmod,a2 ; End of next chunky line + Chunky source modulo
BRA c2p030loop
c2p030skip
MOVEM.l (a7)+,a0-a1
MOVE.w c2p_RowsStore,c2p_Rows ; Has to be reset. Also see start of statement
MOVE.w c2p_Pixels,a2 ; Has to be reset!
ADD.l a0,a2
ADD.l #PlaneSize*4,a1
c2pSMC030
c2p030loop2
MOVE.l (a0)+,d0
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l #$f0f0f0f0,d4 ; Merge 4x1, part 1
AND.l d4,d0
AND.l d4,d2
LSR.l #4,d2
OR.l d2,d0
AND.l d4,d1
AND.l d4,d3
LSR.l #4,d3
OR.l d3,d1
MOVE.l d1,a3
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l (a0)+,d7
AND.l d4,d2 ; Merge 4x1, part 2
AND.l d4,d1
LSR.l #4,d1
OR.l d1,d2
AND.l d4,d3
AND.l d4,d7
LSR.l #4,d7
OR.l d7,d3
MOVE.l a3,d1
ADD.l #0,a0 ; #8*4 Custom verticle interlacing
c2pSMCL011
MOVE.w d2,d7 ; Swap 16x2
MOVE.w d0,d2
SWAP d2
MOVE.w d2,d0
MOVE.w d7,d2
MOVE.w d3,d7
MOVE.w d1,d3
SWAP d3
MOVE.w d3,d1
MOVE.w d7,d3
BRA c2pStart030b
c2pX030b
ADD.l #PlaneSize,a1
c2pSMC031
MOVE.l (a0)+,d0
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
; MOVE.l d7,PlaneSize(a1)
MOVE.l d7,(a1)
MOVE.l #$f0f0f0f0,d4 ; Merge 4x1, part 1
AND.l d4,d0
AND.l d4,d2
LSR.l #4,d2
OR.l d2,d0
SUB.l #PlaneSize,a1
c2pSMC032
AND.l d4,d1
AND.l d4,d3
LSR.l #4,d3
OR.l d3,d1
MOVE.l d1,a3
MOVE.l (a0)+,d2
MOVE.l (a0)+,d1
MOVE.l (a0)+,d3
MOVE.l (a0)+,d7
MOVE.l a4,(a1)+
AND.l d4,d2 ; Merge 4x1, part 2
AND.l d4,d1
LSR.l #4,d1
OR.l d1,d2
AND.l d4,d3
AND.l d4,d7
LSR.l #4,d7
OR.l d7,d3
MOVE.l a3,d1
ADD.l #0,a0 ; #8*4 Custom verticle interlacing
c2pSMCL012
MOVE.w d2,d7 ; Swap 16x2
MOVE.w d0,d2
SWAP d2
MOVE.w d2,d0
MOVE.w d7,d2
ADD.l #-PlaneSize-4,a1
c2pSMC033
MOVE.w d3,d7
MOVE.w d1,d3
SWAP d3
MOVE.w d3,d1
MOVE.w d7,d3
; MOVE.l a5,-PlaneSize-4(a1)
MOVE.l a5,(a1)
SUB.l #-PlaneSize-4,a1
c2pSMC034
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL013
c2pStart030b
MOVE.l a6,d4
MOVE.l d2,d7 ; Swap 2x2
LSR.l #2,d7
EOR.l d0,d7
AND.l d5,d7
EOR.l d7,d0
LSL.l #2,d7
EOR.l d7,d2
MOVE.l d3,d7
LSR.l #2,d7
EOR.l d1,d7
AND.l d5,d7
EOR.l d7,d1
LSL.l #2,d7
EOR.l d7,d3
ADD.l #PlaneSize*2,a1
c2pSMC035
MOVE.l d1,d7
LSR.l #8,d7
EOR.l d0,d7
AND.l d4,d7
EOR.l d7,d0
LSL.l #8,d7
EOR.l d7,d1
MOVE.l d1,d7
LSR.l #1,d7
EOR.l d0,d7
AND.l d6,d7
EOR.l d7,d0
; MOVE.l d0,PlaneSize*2(a1)
MOVE.l d0,(a1)
ADD.l d7,d7
EOR.l d1,d7
MOVE.l d3,d1
LSR.l #8,d1
EOR.l d2,d1
AND.l d4,d1
EOR.l d1,d2
LSL.l #8,d1
EOR.l d1,d3
SUB.l #PlaneSize*2,a1
c2pSMC036
MOVE.l d3,d1
LSR.l #1,d1
EOR.l d2,d1
AND.l d6,d1
EOR.l d1,d2
ADD.l d1,d1
EOR.l d1,d3
MOVE.l d2,a4
MOVE.l d3,a5
CMPA.l a0,a2
BGT c2pX030b
; MOVE.l d7,PlaneSize(a1)
ADD.l #PlaneSize,a1
c2pSMC037
MOVE.l d7,(a1)
SUB.l #PlaneSize,a1
c2pSMC038
MOVE.l a4,(a1)+
; MOVE.l a5,-PlaneSize-4(a1)
ADD.l #-PlaneSize-4,a1
c2pSMC039
MOVE.l a5,(a1)
SUB.l #-PlaneSize-4,a1
c2pSMC040
ADD.l #0,a1 ; #4 Custom verticle interlacing
c2pSMCL014
;YLoop
SUB.w #1,c2p_Rows
BLT c2p030skip2
c2p030nextrow2
ADD.w c2p_Pixels,a2 ; End of next chunky line
ADD.w c2p_Pmod,a1 ; Planar dest modulo
ADD.w c2p_Cmod,a0 ; Chunky source modulo
ADD.w c2p_Cmod,a2 ; End of next chunky line + Chunky source modulo
BRA c2p030loop2
c2p030skip2
c2pNone030a
MOVEM.l (a7)+,a3-a6
RTS ; Finish
;*************************************************************************************
._MReservec2pWindows
;Reserve memory for c2pWindow structures
MOVE.l d0,d7
TST.l c2pWindowsMem ; Check for existing mem allocated
BEQ Reservec2pWskip ; If exists, deallocate
MOVE.w c2pWindowsTotal,d0
EXT.l d0
LSL.l #c2pWindowStructSize,d0
MOVE.l c2pWindowsMem,a1
ALibJsr #BlitzFreemem ; Free memory
MOVE.l d7,d0
MOVE.w #0,c2pWindowsTotal
MOVE.l #0,c2pWindowsMem
Reservec2pWskip
AND.l #$FFFF,d0
MOVE.w d0,d7
LSL.l #c2pWindowStructSize,d0
MOVE.l #ClearPublicMem,d1 ; MemType (public and clear)
!CheckAvailMem{003}
TST.b d2 ; Likely?
BEQ Reservec2pWfailed
ALibJsr #BlitzAllocmem ; Allocate memory
TST.l d0
BEQ Reservec2pWfailed
MOVE.l d0,c2pWindowsMem
MOVE.w d7,c2pWindowsTotal
RTS ; Return memory address in d0.l
Reservec2pWfailed
MOVEQ.l #0,d0 ; Errorcode
RTS
;*************************************************************************************
_MFreec2pWindowsRange
;Free a range of c2pWindow objects
SUB.w d0,d1 ; Total
MOVE.w d1,d3 ; Loopcounter, no need for -1
MOVE.w d0,d4 ; Start offset
Freec2pWRloop
MOVE.w d3,d0
ADD.w d4,d0
BSR _MFreec2pWindow
DBRA d3,Freec2pWRloop
RTS
._MFreec2pWindows
;Free all c2pWindow objects
MOVE.w c2pWindowsTotal,d3
SUBQ.w #1,d3 ; loopcounter
Freec2pWloop
MOVE.w d3,d0
BSR _MFreec2pWindow ; Free it
DBRA d3,Freec2pWloop
RTS
;*************************************************************************************
._MFreec2pWindow
;Free a single c2pWindow object. No actual memory to free so just make inactive
!Getc2pWindowObjectPtr ; Base into a0
TST.l c2p0_Pixels-c2pWindows(a0) ; Test Pixels and RowsStore
BEQ Freec2pWSkip
MOVE.l #0,c2p0_Pixels-c2pWindows(a0) ; Make it dead
Freec2pWSkip
RTS
;*************************************************************************************
._MAddrc2pWindow
;Returns the address of the specified c2pWindow structure
!Getc2pWindowObjectPtr ; In a0
MOVE.l a0,d0 ; Return address
RTS
;*************************************************************************************
._MUsec2pWindows
;Set the currently used c2pWindows
MOVE.w d2,Currentc2pWindow3
_MUsec2pWindowsShort
MOVE.w d1,Currentc2pWindow2
_MUsec2pWindowsShortest
MOVE.w d0,Currentc2pWindow1
RTS
;*************************************************************************************
._MUsec2pWindow
;Set the currently used main c2pWindow
MOVE.w d0,Currentc2pWindow1
RTS
;*************************************************************************************
._MUsedc2pWindow
;Returns number of main currently used c2pWindow, or likely -1 if not defined
MOVE.w Currentc2pWindow1,d0
RTS
;*************************************************************************************
._MAutoUsec2pWindows
MOVE.b d0,Autoc2pWindowsUse
RTS
;*************************************************************************************
._MCopyc2pWindow
_MCopyc2pWindowStruct
;Creat a new c2pWindow from an existing one, copying only definition data
EXG.l d0,d1
!Getc2pWindowObjectPtr ; Base in a0
EXG.l d0,d1
MOVE.l a0,a1 ; Dest
!Getc2pWindowObjectPtr ; Base in a0 - Source
MOVE.w c2p0_Pixels-c2pWindows(a0),c2p0_Pixels-c2pWindows(a1)
MOVE.w c2p0_RowsStore-c2pWindows(a0),c2p0_RowsStore-c2pWindows(a1)
MOVE.w c2p0LaceOffsetA-c2pWindows(a0),c2p0LaceOffsetA-c2pWindows(a1)
MOVE.w c2p0LaceOffsetB-c2pWindows(a0),c2p0LaceOffsetB-c2pWindows(a1)
MOVE.w c2p0_Cmod-c2pWindows(a0),c2p0_Cmod-c2pWindows(a1)
MOVE.w c2p0_Pmod-c2pWindows(a0),c2p0_Pmod-c2pWindows(a1)
MOVE.b c2p0Lace-c2pWindows(a0),c2p0Lace-c2pWindows(a1)
TST.b Autoc2pWindowsUse ; Use it?
BEQ MCopyc2pWStructDontUse ; No
MOVE.w d1,Currentc2pWindow1 ; Yes, store c2pWindow number in current
MCopyc2pWStructDontUse
RTS
;*************************************************************************************
._MGenericPtr
;Given a base address, xpos, ypos, and width, work out an address and return it
MULU d3,d1 ; Width*Ypos
EXT.l d0
ADD.l d0,d1 ; Add Xpos
ADD.l d2,d1 ; Add base address
MOVE.l d1,d0 ; Return longword in d0.l
RTS
;*************************************************************************************
.Data
Even4
c2pLace: Dc.b 0 ; Interlaced c2p (0=No, <>0=Yes)
c2pLaceFrame: Dc.b 0 ; Interlace frame (line offset, 0 or 1 for even/odd)
c2p040useable: Dc.b 1 ; Allow 040 c2p routines to be used ever (0=No, <>0=Yes)
c2pCPUmode: Dc.b 1 ; 0=000-030, 1=040-060 c2p routine to use
c2pColumns: Dc.b 0 ; Column lacing c2p (0=No, <>0=Yes)
c2pColumnsFrame:Dc.b 0 ; Column frame (longword offset, 0 or 1 for leftmost or second to left)
c2p_Rows: Dc.w 0 ; Temporary
c2p_RowsStore: Dc.w 0 ; Temporary
c2p_Pixels: Dc.w 0 ; Temporary
c2p_Pmod: Dc.w 0 ; Temporary
c2p_Cmod: Dc.w 0 ; Temporary
Even4
c2pWindowsMem: Dc.l 0 ; Pointer to mem reserved for c2pWindow structures
c2pWindowsTotal:Dc.w 0 ; Total number of c2p windows (do -1 for highest)
Autoc2pWindowsUse: Dc.b 1 ; Automatically use new c2pWindows? 0=No, <>0=Yes
Even4
Currentc2pWindows:
Currentc2pWindow1: Dc.w -1 ; Number of current c2pWindow
Currentc2pWindow2: Dc.w -1 ; Number of second current c2pWindow
Currentc2pWindow3: Dc.w -1 ; Number of third current c2pWindow
;c2pWindow structure, 16 bytes
c2pWindows
c2p0_Pixels: Dc.w 0 ;0 Number of pixels per row
c2p0_RowsStore: Dc.w 0 ;2 Row counter
c2p0LaceOffsetA:Dc.w 0 ;4 Interlace bytes to add to source pointer in odd frames
c2p0LaceOffsetB:Dc.w 0 ;6 Interlace bytes to add to dest pointer in odd frames
c2p0_Pmod: Dc.w 0 ;8 Planar line modulo
c2p0_Cmod: Dc.w 0 ;10 Chunky line modulo
c2p0Lace: Dc.b 0 ;12 Same as Row-Lacing yes/no. Tells if rowlace was on when object was created
c2p0Pad0: Dc.b 0 ;13
c2p0Pad1: Dc.w 0 ;14
;== 8< =================== 8< ============================= 8< ================= 8< ==
Even4
RunErrors ; Runtime error routines. Everything below this point is discarded if
; compiled without runtime errorchecking switched on
.Checks
;*************************************************************************************
_Mc2pLaceToggleDoubleCheck
TST.b d0
BLT Error15 ; Too small
CMP.b #1,d0
BGT Error15 ; Too large
RTS
;*************************************************************************************
_Mc2pLaceToggleTripleCheck
TST.b d0
BLT Error13 ; Too small
CMP.b #2,d0
BGT Error13 ; Too large
RTS
;*************************************************************************************
_Mc2pLaceToggleCheck
TST.b d0
BLE Error12 ; Too small
CMP.b #3,d0
BGT Error12 ; Too large
TST.b d1
BLT Error13 ; Too small
CMP.b #2,d1
BGT Error13 ; Too large
MOVE.b d1,d7
ADDQ.l #1,d7
CMP.b d0,d7
BGT Error14 ; Current buffer mustn't be of higher index than number of available buffers
RTS
;*************************************************************************************
_Mc2pCPUmodeCheck
TST.b d0
BLT Error7 ; Too small
CMP.b #4,d0
BGT Error7 ; Too large
RTS
;*************************************************************************************
_Mc2pWindowBriefShortCheck
!CCheckc2pWindowsExist
BRA _Mc2pWindowCheckFirst3
;RTS not needed
_Mc2pWindowBriefCheck
!CCheckc2pWindowsExist
BSR _Mc2pWindowCheckFirst3
TST.b d3
BLT Error7 ; Too small
CMP.b #4,d3
BGT Error7 ; Too large
RTS
_Mc2pWindowShortCheck
!CCheckc2pWindowsExist
BSR _Mc2pWindowCheckFirst3
TST.w d3
BLE Error8 ; Too small or larger than signed word
TST.w d4
BLE Error9 ; Too small or larger than signed word
MOVE.w d4,d7
AND.w #$1F,d7
TST.w d7
BNE Error10 ; Planar Width not multiple of 32
TST.w d5
BLE Error11 ; Too small or larger than signed word
RTS
_Mc2pWindowCheck
!CCheckc2pWindowsExist
BSR _Mc2pWindowCheckFirst3
TST.w d3
BLE Error8 ; Too small or larger than signed word
TST.b d4
BLT Error7 ; Too small
CMP.b #4,d4
BGT Error7 ; Too large
TST.w d5
BLE Error9 ; Too small or larger than signed word
MOVE.w d5,d7
AND.w #$1F,d7
TST.w d7
BNE Error10 ; Planar Width not multiple of 32
TST.w d6
BLE Error11 ; Too small or larger than signed word
RTS
_Mc2pWindowCheckFirst3
!CCheckc2pWindowNum
TST.w d1
BLE Error4 ; Too small or larger than signed word
MOVE.w d1,d7
AND.w #$1F,d7
TST.w d7
BNE Error5 ; OpWidth not multiple of 32
TST.w d2
BLE Error6 ; Too small or larger than signed word
RTS
;*************************************************************************************
_Mc2pWindowWidthCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_Mc2pWindowHeightCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_Mc2pWindowNewHeightCheck
!CThreec2pWindowChecks
TST.w d1
BLE Error3 ; Too small or larger than signed word
RTS
;*************************************************************************************
_Mc2pCheck
!CThreec2pWindowChecks
TST.l d1
BEQ Error1 ; Too small
TST.l d2
BEQ Error2 ; Too small
RTS
;*************************************************************************************
_MReservec2pWindowsCheck
!CCheckWordParam2
RTS
;*************************************************************************************
_MFreec2pWindowsRangeCheck
;Not really feasible to check existence of every c2pWindow in the range
!CCheckc2pWindowsExist
EXG.l d0,d1
!CCheckc2pWindowNum
EXG.l d0,d1
!CCheckc2pWindowNum
CMP.w d0,d1
BLT Error36 ; First>Last
RTS
_MFreec2pWindowsCheck
!CCheckc2pWindowsExist
RTS
;*************************************************************************************
_MFreec2pWindowCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_MAddrc2pWindowCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_MUsec2pWindowsCheck
EXG.l d2,d0
!CThreec2pWindowChecks
EXG.l d2,d0
_MUsec2pWindowsShortCheck
EXG.l d1,d0
!CThreec2pWindowChecks
EXG.l d1,d0
_MUsec2pWindowsShortestCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_MUsec2pWindowCheck
!CThreec2pWindowChecks
RTS
;*************************************************************************************
_MUsedc2pWindowCheck
!CCheckc2pWindowsExist
TST.w Currentc2pWindow1
BLT Error26 ; Not used
RTS
;*************************************************************************************
_MCopyc2pWindowStructCheck
EXG.l d0,d1
!CCheckc2pWindowsExist
!CCheckc2pWindowNum ; Dest doesn't have to exist
EXG.l d0,d1
!CThreec2pWindowChecks ; Source MUST exist
RTS
;*************************************************************************************
_MGenericPtrCheck
TST.w d3 ; Width okay?
BLE Error64
TST.l d2 ; Address likely?
BEQ Error65
;Allow xpos,ypos to be negative
RTS
;*************************************************************************************
.Messages
Error0: MOVE.l #Error0Txt,d0 : TRAP #0
Error1: MOVE.l #Error1Txt,d0 : TRAP #0
Error2: MOVE.l #Error2Txt,d0 : TRAP #0
Error3: MOVE.l #Error3Txt,d0 : TRAP #0
Error4: MOVE.l #Error4Txt,d0 : TRAP #0
Error5: MOVE.l #Error5Txt,d0 : TRAP #0
Error6: MOVE.l #Error6Txt,d0 : TRAP #0
Error7: MOVE.l #Error7Txt,d0 : TRAP #0
Error8: MOVE.l #Error8Txt,d0 : TRAP #0
Error9: MOVE.l #Error9Txt,d0 : TRAP #0
Error10: MOVE.l #Error10Txt,d0 : TRAP #0
Error11: MOVE.l #Error11Txt,d0 : TRAP #0
Error12: MOVE.l #Error12Txt,d0 : TRAP #0
Error13: MOVE.l #Error13Txt,d0 : TRAP #0
Error14: MOVE.l #Error14Txt,d0 : TRAP #0
Error15: MOVE.l #Error15Txt,d0 : TRAP #0
Error16: MOVE.l #Error16Txt,d0 : TRAP #0
Error17: MOVE.l #Error17Txt,d0 : TRAP #0
Error18: MOVE.l #Error18Txt,d0 : TRAP #0
Error25: MOVE.l #Error25Txt,d0 : TRAP #0
Error26: MOVE.l #Error26Txt,d0 : TRAP #0
Error36: MOVE.l #Error36Txt,d0 : TRAP #0
Error60: MOVE.l #Error60Txt,d0 : TRAP #0
Error64: MOVE.l #Error64Txt,d0 : TRAP #0
Error65: MOVE.l #Error65Txt,d0 : TRAP #0
Error0Txt: Dc.b "c2pWindow number out of range",0
Error1Txt: Dc.b "Chunky address of zero is not allowed",0
Error2Txt: Dc.b "Planar address of zero is not allowed",0
Error3Txt: Dc.b "Requested new height is out of range",0
Error4Txt: Dc.b "Operation/Window width is out of range",0
Error5Txt: Dc.b "Operation/Window width should be a multiple of 32!",0
Error6Txt: Dc.b "Operation/Window height is out of range",0
Error7Txt: Dc.b "Processor should be in the range 0..4 (4=040,<4=030)",0
Error8Txt: Dc.b "Source Byte-Width (bytes per rasterline) is out of range",0
Error9Txt: Dc.b "Width of planar display is out of range",0
Error10Txt: Dc.b "Width of planar display must be a multiple of 32 pixels",0
Error11Txt: Dc.b "Height of planar display is out of range",0
Error12Txt: Dc.b "Buffering should be 1 (single), 2 (double) or 3 (triple)",0
Error13Txt: Dc.b "Current buffer should be 0, 1 or 2",0
Error14Txt: Dc.b "Specified current-buffer number too high",0
Error15Txt: Dc.b "Current buffer should be 0 or 1",0
Error16Txt: Dc.b "c2pWindows not available. Use MReservec2pWindows",0
Error17Txt: Dc.b "The specified c2pWindow object is undefined",0
Error18Txt: Dc.b "Number of objects shouldn't be more than signed-word limit",0
Error25Txt: Dc.b "Number of objects should be greater than 0",0
Error26Txt: Dc.b "No currently used c2pWindow object",0
Error36Txt: Dc.b "First c2pWindow shouldn't be greater than Second c2pWindow",0
Error60Txt: Dc.b "Number of items out of range",0
Error64Txt: Dc.b "Width should be greater than 0",0
Error65Txt: Dc.b "Address of 0 is not allowed",0
Even4